import { Injectable } from '@angular/core';
import { Request, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { filter, map, catchError, tap  } from 'rxjs/operators';
import { Router } from "@angular/router";
import 'rxjs/add/operator/catch';
import utils from "../config";
import notify from 'devextreme/ui/notify';
// import { message } from "../message";
import { alert, confirm } from "devextreme/ui/dialog";
declare const  ENCODEFN: any;
declare const  NotFoundMap: any;
declare const  LoginAddress: string;
@Injectable()
export class HttpInterceptor {
    constructor(public router: Router){

    }
    // 请求发出前的处理逻辑
    beforeRequest(req: Request) {
        console.log("当前api: ", req.url);
        if(!utils.ipMap.isEncrypt){
            return req;
        }
        utils.ipMap.debugger && console.log(`加密前request: `, req);
        let header: Headers = req.headers;
        // is POST method and has File 
        let isFileRequest = false;
        let ck = '';

        //处理FormData类型
        if (req.getBody() instanceof FormData) {
            utils.ipMap.debugger && console.log(`该请求体是FORMDATA对象 = `, req.getBody());
            isFileRequest = true;
        } // is FormData end  
        if(!isFileRequest){
            ck = utils.encode3(utils.getToken() + req.getBody());
            req["_body"] = `${ck}`;
        }
        header.set("token", utils.getToken());
        req.headers = header;
        return req;
    }//beforeRequest end

    // 请求响应后的处理逻辑
    afterResponse(res: Observable<Response>): Observable<any> {
        
        return res
        .pipe(
            // catch Error
            catchError(e=>{
                console.log(e);
                // this.router.navigate(["main/example/demo"])
                return e;
            }),
            // decode function
            map((x:Response)=>{
                if(!utils.ipMap.isEncrypt){
                    return x;
                }
                const encodeUrl = x["_body"];
                utils.ipMap.debugger && console.log(x);
                let isentry = x.headers.get('isentry');
                utils.ipMap.debugger && console.log('isentry = ',isentry);
                const isBlob = Object.prototype.toString.call(encodeUrl) === "[object Blob]";
                console.log("isBlob = ", isBlob);
                if (isBlob) {
                    return x;
                }
                if(utils.ipMap.isEncrypt && isentry == 'true' && !isBlob){
                    // console.log(encodeUrl);
                    const decodeObj =  ENCODEFN. d de(encodeUrl.replace(/"/g,''));
                    //utils.ipMap.debugger && console.log(decodeObj);
                    if(decodeObj.successful == false){
                        try {
                            let json = JSON.parse(encodeUrl);
                            if(typeof json == 'object' && json){
                                x["_body"] = encodeUrl;
                                return x;
                            }
                            console.log("密文被篡改");
                            notify({
                                message: "数据完整性被破坏，请联系管理员。",
                                position: {
                                    my: 'center top',
                                    at: 'center top'
                                }
                            }, 'error', 3000);
                            x["_body"] = JSON.stringify({"resultHint":"PES_900-数据完整性被破坏，请联系管理员","resultValue":"","successful":false,"type":"error"})
                            return x;
                        } catch (error) {
                            console.log("密文被篡改");
                            notify({
                                message: "数据完整性被破坏，请联系管理员。",
                                position: {
                                    my: 'center top',
                                    at: 'center top'
                                }
                            }, 'error', 3000);
                            x["_body"] = JSON.stringify({"resultHint":"PES_900-数据完整性被破坏，请联系管理员","resultValue":"","successful":false,"type":"error"})
                            return x;
                        }
                        
                    }
                    
                    let _selfTk = utils.getToken();
                    if(_selfTk !== decodeObj.tk){
                        // message("tk 校验失败, 请检查", "error");
                        //console.error("tk 校验失败, 请检查");
                        throw new Error("tk 校验失败, 请检查");
                    }

                    let newAbs = "";
                    try {
                    newAbs =  ENCODEFN.sm3Encrypt(_selfTk + decodeObj.res);
                    } catch (e) {
                        throw new Error("摘要失败");
                    }

                    utils.ipMap.debugger && console.log("当前tk", _selfTk);
                    utils.ipMap.debugger && console.log(x.url , "当前decodeObject = ", decodeObj);

                    if(newAbs !== decodeObj.abs){
                        throw new Error("倆次摘要值不相等, 请检查token");
                    };
                    x["_body"] = decodeObj.res;
                    return x;
                    // let res: Body = new Body(res)
                    // console.log(res)
                    // return res;
                    // return decodeObj.res;
                    // return {
                    //     body:JSON.parse(decodeObj.res),
                    //     json:function(){
                    //         return this.body;
                    //     }
                    // };
                }else{
                    return x;
                }//isEncrypt == false end
            }),
            // map end
            // CommonException
            tap((response: Response)=>{
                try {
                    const CommonException =  NotFoundMap;
                    const targetJson = response.json();
                    const needStr = targetJson["resultHint"] || "";
                    console.log("通用异常拦截", response.json());
                    let isLoginOut = needStr.startsWith(CommonException["PES_904"]) || needStr.startsWith(CommonException["PES_013"]) || needStr.startsWith(CommonException["PES_003"]) || needStr.startsWith(CommonException["PES_004"]);
                    let isDecodeFail = needStr.startsWith(CommonException["PES_900"]) || needStr.startsWith(CommonException["PES_901"]) || needStr.startsWith(CommonException["PES_902"]) || needStr.startsWith(CommonException["PES_903"]);                    
                    if ( !targetJson.successful && isLoginOut ) {
                        this.router.navigate(["/main/auth/logout"]);
                    }
                    else if(!targetJson.successful && isDecodeFail){
                        notify({
                                message: "数据完整性被破坏，请联系管理员。",
                                position: {
                                    my: 'center top',
                                    at: 'center top'
                                }
                            }, 'error', 3000);
                    }
                } catch (error) {
                    console.log("通用异常拦截:", error)
                }
            })
        )        
    }
}

